{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"http://landlab.github.io\"><img style=\"float: left\" src=\"../../media/landlab_header.png\"></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The deAlmeida Overland Flow Component "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<hr>\n",
    "<small>For more Landlab tutorials, click here: <a href=\"https://landlab.readthedocs.io/en/latest/user_guide/tutorials.html\">https://landlab.readthedocs.io/en/latest/user_guide/tutorials.html</a></small>\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook illustrates running the deAlmeida overland flow component in an extremely simple-minded way on a real topography, then shows it creating a flood sequence along an inclined surface with an oscillating water surface at one end.\n",
    "\n",
    "First, import what we'll need:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from landlab.components.overland_flow import OverlandFlow\n",
    "from landlab.plot.imshow import imshow_grid\n",
    "from landlab.plot.colors import water_colormap\n",
    "from landlab import RasterModelGrid\n",
    "from landlab.io.esri_ascii import read_esri_ascii\n",
    "from matplotlib.pyplot import figure\n",
    "import numpy as np\n",
    "from time import time\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pick the initial and run conditions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "run_time = 100  # duration of run, (s)\n",
    "h_init = 0.1  # initial thin layer of water (m)\n",
    "n = 0.01  # roughness coefficient, (s/m^(1/3))\n",
    "g = 9.8  # gravity (m/s^2)\n",
    "alpha = 0.7  # time-step factor (nondimensional; from Bates et al., 2010)\n",
    "u = 0.4  # constant velocity (m/s, de Almeida et al., 2012)\n",
    "run_time_slices = (10, 50, 100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Elapsed time starts at 1 second. This prevents errors when setting our boundary conditions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "elapsed_time = 1.0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use Landlab methods to import an ARC ascii grid, and load the data into the field that the component needs to look at to get the data. This loads the elevation data, z, into a \"field\" in the grid itself, defined on the nodes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rmg, z = read_esri_ascii('Square_TestBasin.asc', name='topographic__elevation')\n",
    "rmg.set_closed_boundaries_at_grid_edges(True, True, True, True)\n",
    "\n",
    "# un-comment these two lines for a \"real\" DEM\n",
    "#rmg, z = read_esri_ascii('hugo_site.asc', name='topographic__elevation') \n",
    "#rmg.status_at_node[z<0.0] = rmg.BC_NODE_IS_CLOSED\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can get at this data with this syntax:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.all(rmg.at_node['topographic__elevation'] == z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that the boundary conditions for this grid mainly got handled with the final line of those three, but for the sake of completeness, we should probably manually \"open\" the outlet. We can find and set the outlet like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_outlet_node = 100  # This DEM was generated using Landlab and the outlet node ID was known\n",
    "rmg.status_at_node[my_outlet_node] = rmg.BC_NODE_IS_FIXED_VALUE"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now initialize a couple more grid fields that the component is going to need:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rmg.add_zeros('surface_water__depth', at='node')  # water depth (m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rmg.at_node['surface_water__depth'] += h_init"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's look at our watershed topography"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "imshow_grid(rmg, 'topographic__elevation')  #, vmin=1650.0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now instantiate the component itself"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "of = OverlandFlow(\n",
    "    rmg, steep_slopes=True\n",
    ")  #for stability in steeper environments, we set the steep_slopes flag to True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we're going to run the loop that drives the component:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "while elapsed_time < run_time:\n",
    "    # First, we calculate our time step.\n",
    "    dt = of.calc_time_step()\n",
    "    # Now, we can generate overland flow.\n",
    "    of.overland_flow()\n",
    "    # Increased elapsed time\n",
    "    print('Elapsed time: ', elapsed_time)\n",
    "    elapsed_time += dt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "imshow_grid(rmg, 'surface_water__depth', cmap='Blues')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's get clever, and run a set of time slices:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "elapsed_time = 1.\n",
    "for t in run_time_slices:\n",
    "    while elapsed_time < t:\n",
    "        # First, we calculate our time step.\n",
    "        dt = of.calc_time_step()\n",
    "        # Now, we can generate overland flow.\n",
    "        of.overland_flow()\n",
    "        # Increased elapsed time\n",
    "        elapsed_time += dt\n",
    "    figure(t)\n",
    "    imshow_grid(rmg, 'surface_water__depth', cmap='Blues')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### Click here for more <a href=\"https://landlab.readthedocs.io/en/latest/user_guide/tutorials.html\">Landlab tutorials</a>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
